package engine

import (
	"code.google.com/p/go8/chip8"
	"code.google.com/p/go8/display"
	"code.google.com/p/go8/games"
	"github.com/gonutz/go-sdl2/sdl"
)

type GameState struct {
	engine         GameEngine
	game           *games.Game
	screenPainter  ScreenPainter
	menu           State
	keyMapCallback func(g *games.Game)
	runner         GameRunner
	quit           chan bool
}

type GameRunner interface {
	Run(game *games.Game)
	Quit()
	Screen() chip8.Screen
}

type ScreenPainter interface {
	SetForegroundColor(c display.Color)
	SetBackgroundColor(c display.Color)
	Paint(chip8.Screen)
}

func NewGameState(e GameEngine, g *games.Game, runner GameRunner, sp ScreenPainter) *GameState {
	gs := &GameState{engine: e, game: g, screenPainter: sp, runner: runner}
	return gs
}

func (gs *GameState) SetMenuState(menu State) {
	gs.menu = menu
}

func (gs *GameState) SetKeyMapCallback(c func(g *games.Game)) {
	gs.keyMapCallback = c
}

func (gs *GameState) Enter() {
	if gs.keyMapCallback != nil {
		gs.keyMapCallback(gs.game)
	}
	gs.screenPainter.SetBackgroundColor(toDisplayColor(gs.game.BackgroundColor))
	gs.screenPainter.SetForegroundColor(toDisplayColor(gs.game.ForegroundColor))
	gs.runner.Run(gs.game)
}

func toDisplayColor(c games.Color) display.Color {
	return display.Color{c.R, c.G, c.B}
}

func (gs *GameState) Exit() {}

func (gs *GameState) HandleEvent(e sdl.Event) {
	switch event := e.(type) {
	case *sdl.KeyDownEvent:
		if event.Keysym.Sym == sdl.K_ESCAPE {
			gs.runner.Quit()
			gs.engine.ChangeState(gs.menu)
		}
	}
}

func (gs *GameState) Draw() {
	gs.screenPainter.Paint(gs.runner.Screen())
}
